﻿using DryWCS.App.Common;
using DryWCS.Model.PLCModel;
using DryWCS.Model.WMS;
using DryWCS.Service.GlobalVariable;
using DryWCS.Service.Stacker;
using DryWCS.Service.WMS;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace DryWCS.App.ViewModel
{
   public  class WarehouseViewModel:ViewModelBase
    {
        //Bing parameter first letter uppercase. Other parameter first letter lowercase.
        #region Parameter 
        string msg = null;
        public int LineNo { get; set; } = 1;
        public int ColNo { get; set; } = 1;
        public int LayerNo { get; set; } = 1; 
        public int Status { get; set; } = 1;
        public string CellStatus { get; set; }
        public float StackerPosition { get; set; } = 130f; 
        public List<Row> line1 { get; set; } = new List<Row>();//first row data information
        public List<Row> line2 { get; set; } = new List<Row>();//second  row data information

        public WareHouseCellInfoService wareHouseCellInfoService = new WareHouseCellInfoService();

        public ObservableCollection<LogModel> Logs { get; set; } = new ObservableCollection<LogModel>();

        public WarehouseStatisticsViewModel WarehouseStatisticsInfo { get; set; } = new WarehouseStatisticsViewModel();

        //location color
        private Dictionary<int, SolidColorBrush> cellColorDic = new Dictionary<int, SolidColorBrush>
        {
            {0,Brushes.Gray },
            {1,Brushes.PaleGreen },
            {2,Brushes.PaleGoldenrod },
            {3,Brushes.PaleTurquoise },
            {4,Brushes.PaleVioletRed },
            {6,Brushes.LightBlue },
            {8,Brushes.Red},
            {10,Brushes.LightCoral },
            {11,Brushes.LightCyan },
            {12,Brushes.LightGoldenrodYellow },
            {13,Brushes.LightPink }
        };
        //location status
        private Dictionary<int, string> cellInfoDic = new Dictionary<int, string>
        {
            {0,"0：无货" },
            {1,"1：有货"  },
            {2,"2：入库预定"  },
            {3,"3：整出预定"  },
            {4,"4：盘/捡预定"  },
            {6,"6：移动预定"  },
            {8,"8：禁止" },
            {10,"10：预留"  },
            {11,"11：已有有货放货"  },
            {12,"12：重复出库"  },
            {13,"13：故障、手动"  }
        };

        public StackerReadModel StackerInfo { get; set; } = new StackerReadModel();

        WareHouseCellInfoService DbMa = new WareHouseCellInfoService();
        #endregion

        #region Constructor
        public WarehouseViewModel()
        {
            //WareHouseCellInfoService DbMa = new WareHouseCellInfoService();
            //DbMa.DbFirst();
            //Insertpostion();
            InitWarehouseInfo();
            Task.Run(() => RefreshWarehouse());
            Task.Run(() => RefreshStacker());
           // List<WareHouseCellInfoModel> cells1 = wareHouseCellInfoService.GetBy(1);
           //(line1[0].Columns[1].CellBg, line1[0].Columns[1].Status) = GetCellColorAndStatus(1, line1[0].Columns[1].LayerNo, line1[0].Columns[1].ColNo, cells1);
            ModifyCellInfo = new RelayCommand(ModifyCellInfoExec);
            CellCommand = new RelayCommand<CellData>(CellCommandExec);
        }
        #endregion

        #region Command
        public RelayCommand ModifyCellInfo { get; set; }
        public RelayCommand<CellData> CellCommand { get; set; }
        #endregion

        #region Warehouse initialization method
        private void InitWarehouseInfo()
        {
            for (int i = 0; i < GV.Line1LayerCount; i++)
            {

                List<CellData> Columns = new List<CellData>();

                for (int j = 0; j < GV.Line1ColCount; j++)
                {
                    Columns.Insert(0, new CellData
                    {
                        CellBg = Brushes.Gray,
                        No = i * GV.Line1ColCount + j + 1,
                        LineNo = 1,
                        ColNo = j + 1,
                        LayerNo = i + 1
                    });
                }

                line1.Add(new Row
                {
                    Columns = Columns
                });


            }


            for (int i = 0; i < GV.Line2LayerCount; i++)
            {

                List<CellData> Columns = new List<CellData>();

                for (int j = 0; j < GV.Line2ColCount; j++)
                {
                    Columns.Insert(0, new CellData
                    {
                        CellBg = Brushes.Gray,
                        No = i * GV.Line2ColCount + j + 1 + GV.Line1ColCount * GV.Line1LayerCount,
                        LineNo = 2,
                        ColNo = j + 1,
                        LayerNo = i + 1
                    });
                }

                line2.Insert(0, new Row
                {
                    Columns = Columns
                });
            }


        }
        #endregion

        #region Refresh window information  Method
        private async Task RefreshWarehouse()
        {
            await Task.Run(() =>
            {
                try
                {
                    while (true)
                    {
                        List<WareHouseCellInfoModel> cells1 = wareHouseCellInfoService.GetBy(1);
                        List<WareHouseCellInfoModel> cells2 = wareHouseCellInfoService.GetBy(2);


                        int full = 0;
                        int empty = 0;
                        int scheduledIn = 0;
                        int scheduledOut = 0;
                        int scheduledPick = 0;
                        int scheduledMove = 0;
                        int forbidden = 0;
                        int reserved = 0;
                        int repeatIn = 0;
                        int repeatOut = 0;
                        int error = 0;

                        for (int i = 0; i < line1.Count; i++)
                        {
                            for (int j = 0; j < line1[i].Columns.Count; j++)
                            {
                                (line1[i].Columns[j].CellBg, line1[i].Columns[j].Status) = GetCellColorAndStatus(1, line1[i].Columns[j].LayerNo, line1[i].Columns[j].ColNo, cells1);

                                switch (line1[i].Columns[j].Status)
                                {
                                    case 0:
                                        empty++;
                                        break;
                                    case 1:
                                        full++;
                                        break;
                                    case 2:
                                        scheduledIn++;
                                        break;
                                    case 3:
                                        scheduledOut++;
                                        break;
                                    case 4:
                                        scheduledPick++;
                                        break;
                                    case 6:
                                        scheduledMove++;
                                        break;
                                    case 8:
                                        forbidden++;
                                        break;
                                    case 10:
                                        reserved++;
                                        break;
                                    case 11:
                                        repeatIn++;
                                        break;
                                    case 12:
                                        repeatOut++;
                                        break;
                                    case 13:
                                        error++;
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }

                        for (int i = 0; i < line2.Count; i++)
                        {
                            for (int j = 0; j < line2[i].Columns.Count; j++)
                            {
                                (line2[i].Columns[j].CellBg, line2[i].Columns[j].Status) = GetCellColorAndStatus(2, line2[i].Columns[j].LayerNo, line2[i].Columns[j].ColNo, cells2);

                                switch (line2[i].Columns[j].Status)
                                {
                                    case 0:
                                        empty++;
                                        break;
                                    case 1:
                                        full++;
                                        break;
                                    case 2:
                                        scheduledIn++;
                                        break;
                                    case 3:
                                        scheduledOut++;
                                        break;
                                    case 4:
                                        scheduledPick++;
                                        break;
                                    case 6:
                                        scheduledMove++;
                                        break;
                                    case 8:
                                        forbidden++;
                                        break;
                                    case 10:
                                        reserved++;
                                        break;
                                    case 11:
                                        repeatIn++;
                                        break;
                                    case 12:
                                        repeatOut++;
                                        break;
                                    case 13:
                                        error++;
                                        break;
                                    default:
                                        break;
                                }
                            }
                            Thread.Sleep(1000);
                        }

                        WarehouseStatisticsInfo.FullCell = full;
                        WarehouseStatisticsInfo.EmptyCell = empty;
                        WarehouseStatisticsInfo.ScheduledInCell = scheduledIn;
                        WarehouseStatisticsInfo.ScheduledOutCell = scheduledOut;
                        WarehouseStatisticsInfo.ScheduledPickCell = scheduledPick;
                        WarehouseStatisticsInfo.ScheduledMoveCell = scheduledMove;
                        WarehouseStatisticsInfo.ForbiddenCell = forbidden;
                        WarehouseStatisticsInfo.ReservedCell = reserved;
                        WarehouseStatisticsInfo.RepeatInCell = repeatIn;
                        WarehouseStatisticsInfo.RepeatOutCell = repeatOut;
                        WarehouseStatisticsInfo.ErrorManualCell = error;

                        WriteLog("测试，查询数据库，更新库位状态");
                        Thread.Sleep(2000);
                    }

                }
                catch (Exception ex)
                {
                    WriteLog($"刷新异常，{ex.Message}");
                }
            });
        }
        #endregion

        #region Refresh Stackerinfo
        private async Task RefreshStacker()
        {
            await Task.Run(() =>
            {
                try
                {
                    while (true)
                    {
                        StackerInfo = GV.StackerData;
                        Thread.Sleep(1000);
                        //temp test 
                        StackerInfo.ColNo = (short)new Random().Next(1,200) ;
                    }
                }
                catch (Exception ex)
                {
                    WriteLog($"刷新堆垛机信息异常，{ex.Message}");
                }
            });
        }
        #endregion

        #region Set cell color Method
        private (SolidColorBrush, int) GetCellColorAndStatus(int lineNo, int row, int col, List<WareHouseCellInfoModel> wareHouseCellInfoModels)
        {
            if(lineNo == 2 && row == 1 && col < 4)
            {

            }
            SolidColorBrush colorBrush = Brushes.White;

            //int? statusTemp1 = wareHouseCellInfoModels.Where(p => p.LINE_NO == 1 && p.LAYER_NO == 1 && p.COL_NO == 16).FirstOrDefault()?.POS_STATUS;
            //int? statusTemp2 = wareHouseCellInfoModels.Where(p => p.LINE_NO == 2 && p.LAYER_NO == 1 && p.COL_NO == 16).FirstOrDefault()?.POS_STATUS;

            int? statusTemp = wareHouseCellInfoModels.Where(p => p.LINE_NO == lineNo && p.LAYER_NO == row && p.COL_NO == col).FirstOrDefault()?.POS_STATUS;
            int status = statusTemp ?? 0;


            if (cellColorDic.ContainsKey(status))
            {
                colorBrush = cellColorDic[status];
            }

            return (colorBrush, status);
        }
        #endregion

        #region ModifyCellInfo
        private void ModifyCellInfoExec()
        {
            int res = wareHouseCellInfoService.UpdateByCell(1, LineNo, ColNo, LayerNo, Status);
          
            if (res == -1)
            {
                msg = "修改失败";
            }
            else
            {
                msg = "修改成功";
            }

            Msg.Info(msg);

        }
        #endregion

        #region Cell Double click event
        private void CellCommandExec(CellData cellData)
        {
            List<Row> data = line1;

            if (cellData.No > GV.Line1LayerCount * GV.Line1ColCount)
            {
                data = line2;
            }

            foreach (var columns in data)
            {
                foreach (var cell in columns.Columns)
                {
                    if (cell.No == cellData.No)
                    {
                        LineNo = cell.LineNo;
                        ColNo = cell.ColNo;
                        LayerNo = cell.LayerNo;
                        Status = cell.Status;

                        CellStatus = cellInfoDic.ContainsKey(cell.Status) ? cellInfoDic[cell.Status] : CellStatus;
                    }
                }
            }
        }
        #endregion

        #region run log
        private void WriteLog(string msg)
        {
            Application.Current?.Dispatcher.Invoke(() =>
            {
                Logs.Add(new LogModel
                {
                    Msg = msg
                });

                if (Logs.Count >= 45)
                {
                    Logs.RemoveAt(0);
                }
            });
        }
        #endregion

        #region 录入货位信息
        public void Insertpostion()
        {
            WareHouseCellInfoModel model = new WareHouseCellInfoModel();
            for(int i = 1; i < 3;i++)
            {
                for(int j = 1; j < 8; j++)
                {
                    for(int k = 1; k < 39; k++)
                    {
                        model.ZONE_ID = 1377;
                        model.POS_TYPE_CODE = "Automated Position";
                        model.LANE_NO = 1;
                        model.LINE_NO = i;
                        model.COL_NO = k;
                        model.LAYER_NO = j;
                        model.ACTIVE_FLAG = true;
                        DbMa.Insert(model);
                    }
                }
            }

            
        }
        #endregion

    }
    public class Row
    {
        public List<CellData> Columns { get; set; }
    }
    public class CellData : ViewModelBase
    {
        private SolidColorBrush cellBg;
        public SolidColorBrush CellBg
        {
            get { return cellBg; }
            set
            {
                cellBg = value;
                this.RaisePropertyChanged("CellBg");
            }
        }

        public int LaneNo { get; set; }

        public int LineNo { get; set; }

        public int ColNo { get; set; }

        public int LayerNo { get; set; }

        private int status;
        public int Status
        {
            get { return status; }
            set
            {
                status = value;
                this.RaisePropertyChanged("Status");
            }
        }

        public int No { get; set; }

    }

    public class LogModel
    {
        public DateTime Time { get; set; } = DateTime.Now;

        public string Msg { get; set; }
    }
}
